#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>

#include <math.h>
#if (defined(__APPLE__))
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#include "repere.h"



void printInfo(char * message, int val1, int val2, int val3);
void DrawPlanObject(double object[], double objectY[], int size_tab, GLdouble hauteur);
void DrawSphere();
void LaunchApp(int argc, char** argv);


#include "Camera.h"
float posCamera[] = {3, 0, 3}; // x,y,z
float lookAtCamera[] = {0, 0, 0}; //x,y,z

int main(int argc, char** argv) {

    //todo menu
    //todo Aide : les commandes
    // choix plein ecran ou non
    LaunchApp(argc, argv);
    return 0;
}

float angleSphere = 1.0f;

void DrawPlanObject(double objectX[], double objectY[], int size_tab, GLdouble hauteur) {
    int i = 0;
    //glBegin(GL_LINE_LOOP);
    glBegin(GL_LINE);

    // glColor3ub(180, 180, 255);
    for (i = 2; i < size_tab - 2; i++) {
        glColor3ub(i * 4, i * 4, 255);
        glVertex3f(objectX[i], objectY[i], hauteur); // origin of the line
        glVertex3f(objectX[i + 1], objectY[i + 1], hauteur); // end of the line
    }
    //Last Segment (bug fix)
    glVertex3f(objectX[size_tab - 2], objectY[size_tab - 2], hauteur); // origin of the line
    glVertex3f(objectX[2], objectY[2], hauteur); // end of the line
    glEnd();

    //    glPushMatrix();
    return;
}

void DrawSphere() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3ub(80, 80, 200);
    GLUquadric* params = gluNewQuadric(); //création du quadrique
    gluQuadricDrawStyle(params, GLU_LINE);
    gluSphere(params, 1, 30, 25);
    glFlush();
}

void LaunchApp(int argc, char** argv) {

    SDL_Event event;
    SDL_Init(SDL_INIT_VIDEO);
    atexit(SDL_Quit);

    SDL_WM_SetCaption("SDL GL Application", NULL);
    SDL_SetVideoMode(1000, 600, 32, SDL_OPENGL); //| SDL_FULLSCREEN);

    Uint32 last_time = SDL_GetTicks();
    Uint32 current_time, ellapsed_time;
    Uint32 start_time;

    SDL_EnableKeyRepeat(100, 100);

    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(70, (double) 640 / 480, 1, 1000);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(posCamera[0], posCamera[1], posCamera[2],
            lookAtCamera[0], lookAtCamera[1], lookAtCamera[2],
            0, 0, 1);

    glEnable(GL_DEPTH_TEST);

    //test : declaration  object Map
    int sizeMap = 360;
    int nbEtage = 11;
    double mapX1[nbEtage][sizeMap];
    double mapY1[nbEtage][sizeMap];
    GLdouble rho; // le rayon du cercle dans un plan
    double rayon = 1; //le rayon de la sphere
    int theta = 0; //l'angle
    double stage = -1;
    int j = 0;
    double radTheta;
    //TODO calculer le nb d'etage en fonction du rayon de la sphere
    //OU alors calcul avec phi :/
    for (j = 0; j < nbEtage; j++) {
        if (stage == -1 || stage == 1) {
            rho = 0.05;
        } else {
            //le rayon du cercle a cette hauteur est:
            rho = sqrt(rayon * rayon - stage * stage);
        }
        stage += 0.2;
        for (theta = 0; theta < sizeMap - 1; theta++) {
            // on passe en radian
            radTheta = theta * M_PI / 180;
            // on enregistre...
            mapX1[j][theta] = rho * cos(radTheta);
            mapY1[j][theta] = rho * sin(radTheta);
        }
    }
    //go
    for (;;) {
        start_time = SDL_GetTicks();
        //capture des evt
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_QUIT:
                    exit(0);
                    break;
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym) {
                        case SDLK_ESCAPE:
                            exit(0);
                            break;

                        case SDLK_BACKSPACE:
                            //reinitialisation de la scene
                            Camera_BACKSPACE();
                            break;
                            /*==================*/
                            /*====== ZOOM =======*/
                            /*==================*/
                        case SDLK_PAGEUP:
                            Camera_PAGEUP();
                            break;
                        case SDLK_PAGEDOWN:
                            Camera_PAGEDOWN();
                            break;
                            /*=========================*/
                            /*====== ORientataion cam =======*/
                            /*========================*/
                        case SDLK_UP:
                            Camera_UP();
                            break;
                        case SDLK_DOWN:
                            Camera_DOWN();
                            break;
                        case SDLK_LEFT:
                            Camera_LEFT();
                            break;
                        case SDLK_RIGHT:
                            Camera_RIGHT();
                            break;
                            /*=========================*/
                            /*====== déplacement cam =======*/
                            /*========================*/
                        case SDLK_z: //avant
                            Camera_z();
                            break;
                        case SDLK_s: //arriere
                            Camera_s();
                            break;
                        case SDLK_q:
                            Camera_q();
                            break;
                        case SDLK_d:
                            Camera_d();
                            break;
                        case SDLK_a:
                            Camera_a();
                            break;
                        case SDLK_e:
                            Camera_e();
                            break;
                        default:
                            break;
                    }//fin du switch exit / other sdl_key
                    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            }//fin du swithc
        }//fin du while
        current_time = SDL_GetTicks();
        ellapsed_time = current_time - last_time;
        last_time = current_time;
        //Pour eviter de tuer le CPU
        ellapsed_time = SDL_GetTicks() - start_time;
        if (ellapsed_time < 10) {
            SDL_Delay(10 - ellapsed_time);
        }

        //GO DESSIN!!
        //DrawSphere();
        GLdouble i = -1;
        int etage = 0;
        for (etage = 0; etage < nbEtage; etage++) {
            DrawPlanObject(mapX1[etage], mapY1[etage], sizeMap, i);
            i += 0.2;
        }
        DrawRepere();

        //pour etre sur de tout flush...
        glFlush();
        //beh il faut ça alors go!
        SDL_GL_SwapBuffers();

    }// fin du for(;;)
    glFlush();
    //beh il faut ça alors go!
    SDL_GL_SwapBuffers();
}
